home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / misc / amigem.lha / amigem / dos / loadseg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-05  |  4.6 KB  |  199 lines

  1. FD1(25,DLONG,LoadSeg,STRPTR name,D1)
  2. {
  3.   struct TagItem tags[1];
  4.   BPTR ret;
  5.   tags[0].ti_Tag=TAG_END;
  6.   ret=NewLoadSeg(name,tags);
  7.   RETURN_DLONG(ret,ret);
  8. }
  9.  
  10. struct Seg
  11. {
  12.   ULONG Size; /* Including this header */
  13.   BPTR  Next; /* or 0 */
  14.   UBYTE Body[0]; /* gcc allows this */
  15. };
  16.  
  17. /* There are certain cases where gotos increase readability :-) */
  18.  
  19. FD2(128,BPTR,NewLoadSeg,STRPTR file,D1,struct TagItem *tags,S2)
  20. {
  21.   ULONG    a,b,first,count=0,i;
  22.   int read=0;
  23.  
  24.   BPTR File=0;
  25.   ULONG NumSegs=0;
  26.   struct Seg **Hunktable=NULL;
  27.  
  28.   if(!(File=Open(file,MODE_OLDFILE)))
  29.     goto error;
  30.  
  31.   /* The first hunk in a segmented image must be HUNK_HEADER */
  32.   if(ReadAll(File,&a,sizeof(ULONG))||a!=HUNK_HEADER)
  33.     goto error;
  34.   for(;;)
  35.   {
  36.     if(ReadAll(File,&a,sizeof(ULONG)))
  37.       goto error;
  38.     if(!a)
  39.       break;
  40.     if(Seek(File,a*sizeof(ULONG),OFFSET_CURRENT)==EOF) /* Skip names */
  41.       goto error;
  42.   }
  43.   if(ReadAll(File,&NumSegs,sizeof(ULONG))||!NumSegs)
  44.     goto error;
  45.   if(ReadAll(File,&first,sizeof(ULONG)))
  46.     goto error;
  47.   if(ReadAll(File,&a,sizeof(ULONG))||a-first!=NumSegs-1)
  48.     goto error;
  49.   if(!(HunkTable=AllocMem(NumSegs*sizeof(struct Seg *),MEMF_ANY|MEMF_CLEAR)))
  50.   { SetIoErr(ERROR_NO_FREE_STORE);
  51.     goto error; }
  52.   for(i=0;i<NumSegs;i++)
  53.   {
  54.     ULONG memflag=MEMF_PUBLIC|MEMF_CLEAR,hunkflag=0;
  55.     if(ReadAll(File,&a,sizeof(ULONG)))
  56.       goto error;
  57.     if(a&HUNKF_CHIP)
  58.     { memflag=MEMF_CHIP|MEMF_CLEAR;
  59.       hunkflag=HUNKF_CHIP;
  60.       a&=~HUNKF_CHIP;
  61.     }else if(a&HUNKF_FAST)
  62.     { memflag=MEMF_FAST|MEMF_CLEAR;
  63.       hunkflag=HUNKF_FAST;
  64.       a&=~HUNKF_FAST; }
  65.     a=sizeof(struct Seg)+a*sizeof(ULONG);
  66.     if(!(HunkTable[i]=AllocMem(a,memflag)))
  67.     { SetIoErr(ERROR_NO_FREE_STORE);
  68.       goto error; }
  69.     HunkTable[i]->Size=a;
  70.     HunkTable[i]->Next=hunkflag;
  71.   }
  72.  
  73.   /* Other hunks */
  74.   do
  75.   {
  76.     if(ReadAll(File,&a,sizeof(ULONG)))
  77.       goto error;
  78.     switch(a)
  79.     {
  80.       case HUNK_CODE:
  81.       case HUNK_DATA:
  82.       case HUNK_BSS:
  83.       case HUNK_CODE|HUNKF_CHIP:
  84.       case HUNK_DATA|HUNKF_CHIP:
  85.       case HUNK_BSS |HUNKF_CHIP:
  86.       case HUNK_CODE|HUNKF_FAST:
  87.       case HUNK_DATA|HUNKF_FAST:
  88.       case HUNK_BSS |HUNKF_FAST:
  89.         if(HunkTable[count]->Next!=(a&(HUNKF_CHIP|HUNKF_FAST)))
  90.           goto error;
  91.         if(ReadAll(File,&b,sizeof(ULONG)))
  92.           goto error;
  93.         b*=sizeof(ULONG);
  94.         if(b>HunkTable[count]->Size-sizeof(struct Seg))
  95.           goto error;
  96.         if((a&~(HUNKF_CHIP|HUNKF_FAST))!=HUNK_BSS)
  97.           if(ReadAll(File,HunkTable[count]->Body,b))
  98.             goto error;
  99.         read=1;
  100.         break;
  101.       case HUNK_ABSRELOC32:
  102.         if(!read)
  103.           goto error;
  104.         for(;;)
  105.         {
  106.           if(ReadAll(File,&a,sizeof(ULONG)))
  107.             goto error;
  108.           if(!a)
  109.             break;
  110.           if(ReadAll(File,&i,sizeof(ULONG)))
  111.             goto error;
  112.           i-=first;
  113.           if(i>=ls->NumSegs)
  114.             goto error;
  115.           while(a--)
  116.           {
  117.             if(ReadAll(File,&b,sizeof(ULONG)))
  118.               goto error;
  119.             if(b>=HunkTable[i]->Size-sizeof(ULONG)-sizeof(struct Seg));
  120.               goto error;
  121.             *(ULONG *)&ls->HunkTable[count]->Body[b]+=(ULONG)HunkTable[i]->Body;
  122.           }
  123.         }        
  124.         break;
  125.       case HUNK_SYMBOL:
  126.         for(;;)
  127.         {
  128.           if(ReadAll(File,&a,sizeof(ULONG)))
  129.             goto error;
  130.           if(!a)
  131.             break;
  132.           if(Seek(File,(a&0xffffff)*sizeof(ULONG),OFFSET_CURRENT)==EOF) /* Skip names */
  133.             goto error;
  134.         }
  135.         break;
  136.       case HUNK_DEBUG:
  137.         if(ReadAll(File,&a,sizeof(ULONG)))
  138.           goto error;
  139.         if(Seek(File,a*sizeof(ULONG),OFFSET_CURRENT)==EOF)
  140.           goto error
  141.         break;
  142.       case HUNK_END:
  143.         count++;
  144.         read=0;
  145.         break;
  146.       default:
  147.         goto error;
  148.     }
  149.   }while(count<NumSegs);
  150.   
  151.   if(!Close(File))
  152.   { File=0; /* Already closed */
  153.     goto error;  }
  154.  
  155.   a=0; /* Prepare hunks for later use */
  156.   for(i=NumSegs-1;i-->0;)
  157.   {
  158.     HunkTable[i]->Next=a;
  159.     a=MKBADDR(&HunkTable[i]->Next);
  160.     CacheClearE(HunkTable[i]->Body,HunkTable[i]->Size-sizeof(struct Seg),CACRF_ClearI);
  161.   }
  162.  
  163.   FreeMem(HunkTable,NumSegs*sizeof(struct Seg *));
  164.  
  165.   return a;
  166.  
  167. error:
  168.  
  169.   if(!IoErr())
  170.     SetIoErr(ERROR_BAD_HUNK);
  171.   
  172.   if(File)
  173.     Close(File);  
  174.  
  175.   if(HunkTable)
  176.   {
  177.     for(i=0;i<NumSegs;i++)
  178.       FreeMem(Hunktable[i],HunkTable[i]->Size);
  179.     FreeMem(HunkTable,NumSegs*sizeof(struct Seg *));
  180.   }
  181.   
  182.   return 0;
  183. }
  184.  
  185. FD1(127,BOOL,UnLoadSeg,BPTR seglist,D1)
  186. {
  187.   if(!seglist)
  188.     return 0;
  189.  
  190.   while(seglist)
  191.   {
  192.     struct Seg *s;
  193.     s=(struct Seg *)((ULONG *)BADDR(seglist)-1);
  194.     seglist=s->Next;
  195.     FreeMem(s,s->Size);
  196.   }
  197.   return DOSTRUE;
  198. }
  199.